namespace Legend.Core.Tests.Integration.Threading
{
    using System;
    using System.Threading;
    using Legend.Threading;
    using NUnit.Framework;

    public abstract class TimerIntegrationTestsBase
    {
        protected abstract TimerFactory CreateTimerFactory();

        private ITimer CreateTimer(TimeSpan interval)
        {
            return this.CreateTimerFactory().Invoke(interval);
        }

        [Test]
        public void Timer_should_call_back_first_time_after_specified_interval()
        {
            // Arrange
            bool hasCalledBack = false;

            using (var timer = this.CreateTimer(TimeSpan.FromMilliseconds(10)))
            {
                timer.Elapsed += (_, e) =>
                    {
                        hasCalledBack = true;
                    };
                timer.Start();

                // Act
                Thread.Sleep(TimeSpan.FromMilliseconds(100));
            }

            // Assert
            Assert.That(hasCalledBack, Is.True);
        }

        [Test]
        public void Timer_should_stop_raising_when_stop_has_been_called()
        {
            // Arrange
            bool hasCalledBack = false;

            using (var timer = this.CreateTimer(TimeSpan.FromMilliseconds(5)))
            {
                timer.Start();

                Thread.Sleep(TimeSpan.FromMilliseconds(5));

                timer.Stop();

                
                timer.Elapsed += (_, e) =>
                {
                    hasCalledBack = true;
                };



                // Act
                Thread.Sleep(TimeSpan.FromMilliseconds(50));
            }
            
            // Assert
            Assert.That(hasCalledBack, Is.False);
        }
    }
}
